package wqh.controller;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import wqh.domain.GeoBuilding;
import wqh.pojo.GeoBuildingTree;
import wqh.pojo.MapRet;
import wqh.service.GeoBuildingService;
import wqh.service.MapPosGeoService;
import wqh.service.MapPosService;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/water/location")
public class GeoBuildingJSONController {

    private static org.slf4j.Logger logger = LoggerFactory.getLogger(GeoBuildingJSONController.class);

    @Autowired
    private GeoBuildingService geoBuildingService;

    @Autowired
    private MapPosService mapPosService;

    @Autowired
    private MapPosGeoService mapPosGeoService;

    @RequestMapping(value = "/getTree", method = RequestMethod.GET)
    public Object getTree(HttpServletRequest request)
    {
        List<GeoBuilding> geoBuildingList = geoBuildingService.findAllRecord();
        for(GeoBuilding g : geoBuildingList)
        {
            g.setPicture("http://"+request.getServerName() + ":" + request.getServerPort() + "/water/file/location/getMap?id=" + g.getId());
        }
        List<GeoBuildingTree> treeList = new ArrayList<GeoBuildingTree>();
        for(int i = 0; i < geoBuildingList.size(); i++)
        {
            int level = geoBuildingList.get(i).getLevel().intValue();
            if(level == 1)
            {
                int level_1_ID = geoBuildingList.get(i).getId();
                GeoBuildingTree tree = new GeoBuildingTree(geoBuildingList.get(i).getId(),
                        geoBuildingList.get(i).getName(),
                        geoBuildingList.get(i).getParent_id(),
                        geoBuildingList.get(i).getLevel(),
                        geoBuildingList.get(i).getPos_x(),
                        geoBuildingList.get(i).getPos_y(),
                        geoBuildingList.get(i).getPicture(),
                        geoBuildingList.get(i).getDescription());
                List<GeoBuildingTree> level2 = new ArrayList<GeoBuildingTree>();
                for(int j = 0; j < geoBuildingList.size(); j++)
                {
                    int parentID;
                    if(geoBuildingList.get(j).getParent_id() == 0 || geoBuildingList.get(j).getName() == null || geoBuildingList.get(j).getLevel().intValue() == 0)
                    {
                        continue;
                    }
                    else
                    {
                        parentID = geoBuildingList.get(j).getParent_id();
                    }
                    if(level_1_ID == parentID)
                    {
                        int level_2_ID = geoBuildingList.get(j).getId();
                        GeoBuildingTree treeLevel2Child = new GeoBuildingTree(geoBuildingList.get(j).getId(),
                                geoBuildingList.get(j).getName(),
                                geoBuildingList.get(j).getParent_id(),
                                geoBuildingList.get(j).getLevel(),
                                geoBuildingList.get(j).getPos_x(),
                                geoBuildingList.get(j).getPos_y(),
                                geoBuildingList.get(j).getPicture(),
                                geoBuildingList.get(j).getDescription());
                        List<GeoBuildingTree> level3 = new ArrayList<GeoBuildingTree>();
                        for(int k = 0; k < geoBuildingList.size(); k++)
                        {
                            int parentID3;
                            if(geoBuildingList.get(k).getParent_id() == 0 || geoBuildingList.get(k).getName() == null || geoBuildingList.get(k).getLevel().intValue() == 0)
                            {
                                continue;
                            }
                            else
                            {
                                parentID3 = geoBuildingList.get(k).getParent_id();
                            }
                            if(level_2_ID == parentID3)
                            {
                                GeoBuildingTree treeLevel3Child = new GeoBuildingTree(geoBuildingList.get(k).getId(),
                                        geoBuildingList.get(k).getName(),
                                        geoBuildingList.get(k).getParent_id(),
                                        geoBuildingList.get(k).getLevel(),
                                        geoBuildingList.get(k).getPos_x(),
                                        geoBuildingList.get(k).getPos_y(),
                                        geoBuildingList.get(k).getPicture(),
                                        geoBuildingList.get(k).getDescription());
                                level3.add(treeLevel3Child);
                            }
                        }
                        treeLevel2Child.setChildren(level3);
                        level2.add(treeLevel2Child);
                    }
                }
                tree.setChildren(level2);
                treeList.add(tree);
            }
        }
        return MapRet.DATA(treeList);
    }

    @RequestMapping(value = "/getArea",method = RequestMethod.GET)
    public Object getArea()
    {
        GeoBuilding g = new GeoBuilding();
        g.setLevel((byte)1);
        List<GeoBuilding> geoBuildingList = geoBuildingService.findRecordByClass2(g);
        if(geoBuildingList.size() == 0) return MapRet.DATA(null);
        List<Object> objectList = new ArrayList<Object>();
        for(GeoBuilding geoBuilding : geoBuildingList)
        {
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("id",geoBuilding.getId());
            map.put("text",geoBuilding.getName());
            objectList.add(map);
        }
        return MapRet.DATA(objectList);
    }

    @RequestMapping(value = "/addArea",method = RequestMethod.POST)
    public Object addArea(@RequestParam(value = "name",required = true) String name)
    {
        try {
            GeoBuilding g = new GeoBuilding();
            g.setLevel((byte)1);
            g.setName(name);
            List<GeoBuilding> oldList= geoBuildingService.findRecordByClass(g);
            if(oldList.size() != 0) return MapRet.SQL_ERROR();
            g.setParent_id(0);
            geoBuildingService.insertRecord(g);
            return MapRet.SQL_SUCCESS();
        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("添加区域信息出错：" + e.toString());
            return MapRet.SQL_ERROR();
        }
    }

    @RequestMapping(value = "/getBuilding",method = RequestMethod.GET)
    public Object getBuilding(@RequestParam(value = "parent_id",required = true) int parent_id)
    {
        GeoBuilding building = new GeoBuilding();
        building.setLevel((byte)2);
        building.setParent_id(parent_id);
        List<GeoBuilding> geoBuildingList = geoBuildingService.findRecordByClass2(building);
        if(geoBuildingList.size() == 0) return MapRet.DATA(null);
        List<Object> objectList = new ArrayList<Object>();
        for(GeoBuilding geoBuilding : geoBuildingList)
        {
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("id",geoBuilding.getId());
            map.put("text",geoBuilding.getName());
            objectList.add(map);
        }
        return MapRet.DATA(objectList);
    }

    @RequestMapping(value = "/addBuilding",method = RequestMethod.POST)
    public Object addBuilding(@RequestParam(value = "name",required = true) String name,
                              @RequestParam(value = "parent_id",required = true) int parent_id)
    {
        try {
            GeoBuilding g = new GeoBuilding();
            g.setLevel((byte)2);
            g.setName(name);
            g.setParent_id(parent_id);
            List<GeoBuilding> oldList= geoBuildingService.findRecordByClass(g);
            if(oldList.size() != 0) return MapRet.SQL_ERROR();
            geoBuildingService.insertRecord(g);
            return MapRet.SQL_SUCCESS();
        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("添加建筑物信息出错：" + e.toString());
            return MapRet.SQL_ERROR();
        }
    }

    @RequestMapping(value = "/getFloor",method = RequestMethod.GET)
    public Object getFloor(@RequestParam(value = "parent_id",required = true) int parent_id)
    {
        GeoBuilding building = new GeoBuilding();
        building.setLevel((byte)3);
        building.setParent_id(parent_id);
        List<GeoBuilding> geoBuildingList = geoBuildingService.findRecordByClass2(building);
        if(geoBuildingList.size() == 0) return MapRet.DATA(null);
        List<Object> objectList = new ArrayList<Object>();
        for(GeoBuilding geoBuilding : geoBuildingList)
        {
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("id",geoBuilding.getId());
            map.put("text",geoBuilding.getName());
            objectList.add(map);
        }
        return MapRet.DATA(objectList);
    }

    @RequestMapping(value = "/addFloor",method = RequestMethod.POST)
    public Object addFloor(@RequestParam(value = "name",required = true) String name,
                              @RequestParam(value = "parent_id",required = true) int parent_id)
    {
        try {
            GeoBuilding g = new GeoBuilding();
            g.setLevel((byte)3);
            g.setName(name);
            g.setParent_id(parent_id);
            List<GeoBuilding> oldList= geoBuildingService.findRecordByClass(g);
            if(oldList.size() != 0) return MapRet.SQL_ERROR();
            geoBuildingService.insertRecord(g);
            return MapRet.SQL_SUCCESS();
        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("添加建筑物信息出错：" + e.toString());
            return MapRet.SQL_ERROR();
        }
    }

    @RequestMapping(value = "/updateName",method = RequestMethod.POST)
    public Object updateName(@RequestParam(value = "id",required = true) int id,
                             @RequestParam(value = "name",required = true) String name)
    {
        try {
            GeoBuilding g = new GeoBuilding();
            g.setId(id);
            g.setName(name);
            geoBuildingService.updateRecord(g);
            return MapRet.SQL_UPDATE_SUCCESS();
        }catch (Exception e) {
            e.printStackTrace();
            logger.error("修改名称出错：" + e.toString());
            return MapRet.SQL_UPDATE_ERROR();
        }
    }

    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public Object delete(HttpServletRequest httpServletRequest, @RequestParam(value = "id",required = true) int id)
    {
        try {
            String serverPath = httpServletRequest.getServletContext().getRealPath("/");
            GeoBuilding g = geoBuildingService.findRecordById(id);
            if(g.getLevel() == 3)
            {
                String dbPath = g.getPicture();
                File file = new File(serverPath + dbPath);
                if(file.isFile() && file.exists()) file.delete();
                deleteGroup(id);
            }
            if(g.getLevel() == 2)
            {
                GeoBuilding geo = new GeoBuilding();
                geo.setLevel((byte)3);
                geo.setParent_id(g.getId());
                List<GeoBuilding> level3 = geoBuildingService.findRecordByClass2(geo);
                if(level3.size() == 0){
                    String dbPath = g.getPicture();
                    File file = new File(serverPath + dbPath);
                    if(file.isFile() && file.exists()) file.delete();
                    deleteGroup(g.getId());
                }
                else{
                    for(GeoBuilding gt : level3){
                        String dbPath = gt.getPicture();
                        File file = new File(serverPath + dbPath);
                        if(file.isFile() && file.exists()) file.delete();
                        deleteGroup(g.getId());
                    }
                    String dbPath = g.getPicture();
                    File file = new File(serverPath + dbPath);
                    if(file.isFile() && file.exists()) file.delete();
                    deleteGroup(g.getId());
                }
            }
            if(g.getLevel() == 1){
                GeoBuilding geo2 = new GeoBuilding();
                geo2.setLevel((byte)2);
                geo2.setParent_id(g.getId());
                List<GeoBuilding> level2 = geoBuildingService.findRecordByClass2(geo2);
                if(level2.size() == 0){
                    String dbPath = g.getPicture();
                    File file = new File(serverPath + dbPath);
                    if(file.isFile() && file.exists()) file.delete();
                    deleteGroup(g.getId());
                }else{
                    for(GeoBuilding g2 : level2){
                        GeoBuilding geo3 = new GeoBuilding();
                        geo3.setLevel((byte)3);
                        geo3.setParent_id(g2.getId());
                        List<GeoBuilding> level3 = geoBuildingService.findRecordByClass2(geo3);
                        if(level3.size() == 0){
                            String dbPath = g2.getPicture();
                            File file = new File(serverPath + dbPath);
                            if(file.isFile() && file.exists()) file.delete();
                            deleteGroup(g.getId());
                        }else{
                            for(GeoBuilding g3 : level3){
                                String dbPath = g3.getPicture();
                                File file = new File(serverPath + dbPath);
                                if(file.isFile() && file.exists()) file.delete();
                                deleteGroup(g3.getId());
                            }
                            String dbPath = g2.getPicture();
                            File file = new File(serverPath + dbPath);
                            if(file.isFile() && file.exists()) file.delete();
                            deleteGroup(g2.getId());
                        }
                    }
                    String dbPath = g.getPicture();
                    File file = new File(serverPath + dbPath);
                    if(file.isFile() && file.exists()) file.delete();
                    deleteGroup(g.getId());
                }
            }

        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("删除设备出错 " + e.toString());
            return MapRet.SQL_ERROR();
        }
        return MapRet.SQL_SUCCESS();
    }

    @RequestMapping(value = "/mapUpload",method = RequestMethod.POST)
    public Object mapUpload(HttpServletRequest httpServletRequest,
                            @RequestParam(value = "file",required = true)MultipartFile file,
                            @RequestParam(value = "id",required = true) int id)
    {
        try{
            GeoBuilding g = geoBuildingService.findRecordById(id);
            if(g == null)
            {
                return MapRet.SQL_SELECT_NONE();
            }
            String localPath = "upload\\map\\";
            String uploadPath = httpServletRequest.getServletContext().getRealPath("/") + localPath;
            if(g.getPicture() != null && g.getPicture().length() != 0 && !g.getPicture().equals("0"))
            {
                String serverPath = httpServletRequest.getServletContext().getRealPath("/") + g.getPicture();
                File serverFile = new File(serverPath);
                if(serverFile.isFile() && serverFile.exists())
                {
                    serverFile.delete();
                }
            }
            File uploadDir = new File(uploadPath);
            if(!uploadDir.exists())
            {
                uploadDir.mkdirs();
            }
            String fileName = file.getOriginalFilename();
            if(fileName != null)
            {
                byte[] bytes = file.getBytes();
                fileName = System.currentTimeMillis() + fileName;
                File serverFile = new File(uploadDir.getAbsolutePath() + File.separator + fileName);
                BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile));
                stream.write(bytes);
                stream.close();
                GeoBuilding geoBuildingUpdate = new GeoBuilding();
                geoBuildingUpdate.setId(id);
                geoBuildingUpdate.setPicture(localPath + serverFile.getName());
                geoBuildingService.updateRecord(geoBuildingUpdate);
            }
        }catch (Exception e){
            logger.error("上传地图出错："+e.toString());
            e.printStackTrace();
            return MapRet.FILE_UPLOAD_ERROR();
        }
        return MapRet.FILE_UPLOAD_SUCCESS();
    }

    private void deleteGroup(Integer id)
    {
        geoBuildingService.deleteRecord(id);
        mapPosService.deleteByGeoId(id);
        mapPosGeoService.deleteByGeoId(id);
    }

}
